home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / 3DGPL 1.0 / CODE / TRANS / TRANS-FL.C next >
Encoding:
C/C++ Source or Header  |  1997-03-08  |  9.6 KB  |  266 lines  |  [TEXT/MACA]

  1. /** 3DGPL *************************************************\
  2.  *  ()                                                    *
  3.  *  3-D transformations of coordinates using floats.      *
  4.  *                                                        *
  5.  *  Defines:                                              *
  6.  *   T_init_math             Creating sin/cos tables;     *
  7.  *                                                        *
  8.  *   T_translation           Shifting of coordinates;     *
  9.  *   T_scaling               Scaling coordinates;         *
  10.  *                                                        *
  11.  *   T_set_world_rotation    Viewer's rotation;           *
  12.  *   T_world_rotation        Transforming coordinates;    *
  13.  *   T_set_self_rotation     Object rotation;             *
  14.  *   T_self_rotation         Transforming coordinates;    *
  15.  *                                                        *
  16.  *   T_perspective           Transform to perspective.    *
  17.  *                                                        *
  18.  *  (6/1995) By Sergei Savchenko. (savs@cs.mcgill.ca).    *
  19.  *  Copyright (c) 1995 Sergei Savchenko.                  *
  20.  *  THIS SOURCE CODE CAN'T BE USED FOR COMERCIAL PURPOSES *
  21.  *  WITHOUT AUTHORISATION                                 *
  22. \**********************************************************/
  23.  
  24. #include <math.h>                           /* sin & cos */
  25.  
  26. #ifdef __MWERKS__
  27. #include "hardware.h"           /* fast copy routines */
  28. #include "trans.h"                 /* 3D mathematics */
  29. #else
  30. #include "../hardware/hardware.h"           /* fast copy routines */
  31. #include "../trans/trans.h"                 /* 3D mathematics */
  32. #endif
  33.  
  34. #define T_RADS                  40.7436642  /* pseudo-grads into rads */
  35.  
  36. float T_wx1,T_wx2,T_wx3,T_wy1,T_wy2,T_wy3,T_wz1,T_wz2,T_wz3;
  37. float T_sx1,T_sx2,T_sx3,T_sy1,T_sy2,T_sy3,T_sz1,T_sz2,T_sz3;
  38. float T_sin[256],T_cos[256];                /* precalculated */
  39.  
  40. /**********************************************************\
  41.  *  Initializing tables.                                  *
  42. \**********************************************************/
  43.  
  44. void T_init_math(void)
  45. {
  46.  int i;
  47.  
  48.  for(i=0;i<256;i++)
  49.  {
  50.   T_sin[i]=sin(i/T_RADS);
  51.   T_cos[i]=cos(i/T_RADS);
  52.  }
  53.  
  54. /**********************************************************\
  55.  *  Translation of coordinates.                           *
  56. \**********************************************************/
  57.  
  58. void T_translation(register int *from,register int *to,int length,
  59.            int addx,int addy,int addz
  60.           )
  61. {
  62.  register int i;
  63.  
  64.  for(i=0;i<length;i++)
  65.  {
  66.   (*to++)=(*from++)+addx;
  67.   (*to++)=(*from++)+addy;
  68.   (*to++)=(*from++)+addz;                   /* translation */
  69.  }
  70. }
  71.  
  72. /**********************************************************\
  73.  *  Scaling coordinates. (takes in float parameters).     *
  74. \**********************************************************/
  75.  
  76. void T_scaling(register int *from,register int *to,int length,
  77.            int mulx,int muly,int mulz
  78.           )
  79. {
  80.  register int i;
  81.  
  82.  for(i=0;i<length;i++)
  83.  {
  84.   (*to++)=(int)(*from++)*mulx;
  85.   (*to++)=(int)(*from++)*muly;
  86.   (*to++)=(int)(*from++)*mulz;
  87.  }                                          /* scaling */
  88. }
  89.  
  90. /**********************************************************\
  91.  *  Constructing rotation matrix. (gam-bet-alp), rotation *
  92.  *  then pitch then roll sequence. gam-rotation, bet-pitch*
  93.  *                                 alp-roll.              *
  94.  *                                                        *
  95.  *          Y^    Z           x'=z*sin(gam)+x*cos(gam)    *  
  96.  *           |   /            y'=y                        *
  97.  *           |  / alp         z'=z*cos(gam)-x*sin(gam)    * 
  98.  *          /|<---+                                       *
  99.  *         | |/   |           x"=x'                       *
  100.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  101.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  102.  *         V/|   /| gam                                   *
  103.  *         /----+             x"'=y"*sin(alp)+x"*cos(alp) *
  104.  *        /  |                y"'=y"*cos(alp)-x"*sin(alp) *
  105.  *       /   |                z"'=z"                      *
  106.  *           |                                            *
  107. \**********************************************************/
  108.  
  109. void T_set_world_rotation(int alp,int bet,int gam)
  110. {
  111.  float cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  112.  
  113.  cosalp=T_cos[alp];
  114.  sinalp=T_sin[alp];
  115.  cosbet=T_cos[bet];
  116.  sinbet=T_sin[bet];
  117.  cosgam=T_cos[gam];
  118.  singam=T_sin[gam];                         /* initializing */
  119.  
  120.  T_wx1=singam*sinbet*sinalp + cosgam*cosalp;
  121.  T_wy1=cosbet*sinalp;
  122.  T_wz1=singam*cosalp - cosgam*sinbet*sinalp;
  123.  
  124.  T_wx2=singam*sinbet*cosalp - cosgam*sinalp;
  125.  T_wy2=cosbet*cosalp;
  126.  T_wz2=-cosgam*sinbet*cosalp - singam*sinalp;
  127.  
  128.  T_wx3=-singam*cosbet;
  129.  T_wy3=sinbet;
  130.  T_wz3=cosgam*cosbet;                       /* calculating the matrix */
  131. }
  132.  
  133. /**********************************************************\
  134.  *  Rotating coordinates.                                 *
  135.  *                                        |wx1 wx2 wx3|   *
  136.  *  T'=T[W]  where:  [x' y' z'] = [x y z]*|wy1 wy2 wy3|   *
  137.  *                                        |wz1 wz2 wz3|   *
  138. \**********************************************************/
  139.  
  140. void T_world_rotation(int *from,register int *to,int length)
  141. {
  142.  register int i;
  143.  register int xt,yt,zt;
  144.  
  145.  for(i=0;i<length;i++)
  146.  {
  147.   xt=*from++;
  148.   yt=*from++;
  149.   zt=*from++;
  150.  
  151.   *to++=(int)(T_wx1*xt+T_wy1*yt+T_wz1*zt);
  152.   *to++=(int)(T_wx2*xt+T_wy2*yt+T_wz2*zt);
  153.   *to++=(int)(T_wx3*xt+T_wy3*yt+T_wz3*zt); 
  154.  }
  155. }
  156.  
  157. /**********************************************************\
  158.  *  Constructing rotation matrix. (alp-bet-gam), roll     * 
  159.  *  then pitch then rotation sequence. gam-rotation,      *
  160.  *                                     bet-pitch, alp-roll*
  161.  *                                                        *
  162.  *          Y^    Z           x'=y*sin(alp)+x*cos(alp)    *   
  163.  *           |   /            y'=y*cos(alp)-x*sin(alp)    *
  164.  *           |  / alp         z'=z                        *
  165.  *          /|<---+                                       *
  166.  *         | |/   |           x"=x'                       *
  167.  *  -------|-+-----------> X  y"=y'*cos(bet)-z'*sin(bet)  *
  168.  *     bet | |   __           z"=y'*sin(bet)+z'*cos(bet)  *
  169.  *         V/|   /| gam                                   *
  170.  *         /----+             x"'=z"*sin(gam)+x"*cos(gam) *
  171.  *        /  |                y"'=y"                      *
  172.  *       /   |                z"'=z"*cos(gam)-x"*sin(gam) *
  173.  *           |                                            *
  174. \**********************************************************/
  175.  
  176. void T_set_self_rotation(int alp,int bet,int gam)
  177. {
  178.  float cosalp,sinalp,cosbet,sinbet,cosgam,singam;
  179.  
  180.  cosalp=T_cos[alp];
  181.  sinalp=T_sin[alp];
  182.  cosbet=T_cos[bet];
  183.  sinbet=T_sin[bet];
  184.  cosgam=T_cos[gam];
  185.  singam=T_sin[gam];                         /* initializing */
  186.  
  187.  T_sx1=cosalp*cosgam-sinalp*sinbet*singam;
  188.  T_sy1=sinalp*cosgam+cosalp*sinbet*singam;
  189.  T_sz1=cosbet*singam;
  190.  
  191.  T_sx2=-sinalp*cosbet;
  192.  T_sy2=cosalp*cosbet;
  193.  T_sz2=-sinbet;
  194.  
  195.  T_sx3=-cosalp*singam-sinalp*sinbet*cosgam;
  196.  T_sy3=cosalp*sinbet*cosgam-sinalp*singam;
  197.  T_sz3=cosbet*cosgam;                       /* calculating the matrix */
  198. }
  199.  
  200. /**********************************************************\
  201.  *  Rotating coordinates.                                 *
  202.  *                                        |sx1 sx2 sx3|   *
  203.  *  T'=T[S]  where:  [x' y' z'] = [x y z]*|sy1 sy2 sy3|   *
  204.  *                                        |sz1 sz2 sz3|   *
  205. \**********************************************************/
  206.  
  207. void T_self_rotation(int *from,register int *to,int length)
  208. {
  209.  register int i;
  210.  register int xt,yt,zt;
  211.  
  212.  for(i=0;i<length;i++)
  213.  {
  214.   xt=*from++;
  215.   yt=*from++;
  216.   zt=*from++;
  217.  
  218.   *to++=(int)(T_sx1*xt+T_sy1*yt+T_sz1*zt);
  219.   *to++=(int)(T_sx2*xt+T_sy2*yt+T_sz2*zt);
  220.   *to++=(int)(T_sx3*xt+T_sy3*yt+T_sz3*zt); 
  221.  }
  222. }
  223.  
  224. /**********************************************************\
  225.  *  Transforming to perspective, coordinates passed ase   *
  226.  *                        supposed to be both volume, and *  
  227.  *                *       Z-clipped, otherwise division   *
  228.  *               /|X      by 0 or overflow can occur.     *
  229.  *              / |                                       *
  230.  *             /  |                                       *
  231.  *            *   |                                       *
  232.  *           /|X' |       X'      X                       *
  233.  *          / |   |    ------- = ---                      *
  234.  *         /  |   |     focus     Z                       *
  235.  *        *---+---+                                       *
  236.  *        0   ^   Z    X'= X*focus/Z                      *
  237.  *            |                                           *
  238.  *          focus                                         *
  239.  *                                                        *
  240.  *  ADDITIONAL FUNCTIONS: 1) changing formats:            *
  241.  *  ---------------------                                 *
  242.  *    source:       x, y ,z,a1,...,aN where N==dimension-3*
  243.  *    destanation:  x',y',  a1,...,aN                     *
  244.  *                                                        *
  245.  *  2) performs translation to the screen centre.         *
  246. \**********************************************************/
  247.  
  248. void T_perspective(register int *from,register int *to,
  249.            int dimension,int length
  250.           )
  251. {
  252.  register int i;
  253.  
  254.  dimension-=3;                              /* other then X,Y */
  255.  
  256.  for(i=0;i<length;i++,from+=dimension,to+=dimension) 
  257.  {                                          /* Z is not being changed */
  258.   to[0]=((((long)from[0])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_X_CENTRE;
  259.   to[1]=((((long)from[1])<<T_LOG_FOCUS)/from[2])+HW_SCREEN_Y_CENTRE;
  260.   HW_copy_int(from+=3,to+=2,dimension);
  261.  }
  262. }
  263.  
  264. /**********************************************************/
  265.